package stream;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 并行流
 */
public class ParallelStream {
    public static void main(String[] args) {
//        getParallelStream();
//        parallelPrint();
        parallelSecure();
    }

    private static void parallelSecure() {
        ArrayList<Integer> list = new ArrayList<>(1000);
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> list.add(i));
        System.out.println("list.size() = " + list.size()); // size < 1000 ,因为ArrayList是线程不安全的

        /**
         * 解决线程安全方案一:使用同步代码块
         */
        ArrayList<Integer> list1 = new ArrayList<>(1000);
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> {
            synchronized (ParallelStream.class) {
                list1.add(i);
            }
        });
        System.out.println("list1.size() = " + list1.size());

        /**
         * 解决线程安全方案二:使用线程安全的集合
         */
        Vector<Integer> list2 = new Vector<>(1000);
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> {
                list2.add(i);
        });
        System.out.println("list2.size() = " + list2.size());

        /**
         * 解决线程安全方案三:使用集合工具类将线程不安全的集合转为安全的集合
         */
        ArrayList<Integer> list3 = new ArrayList<>(1000);
        List<Integer> synchronizedList = Collections.synchronizedList(list3);
        IntStream.rangeClosed(1,1000).parallel().forEach(i -> synchronizedList.add(i));
        System.out.println("synchronizedList.size() = " + synchronizedList.size());

        /**
         * 解决线程安全方案四:使用Stream的collect/toArray
         */
        List<Integer> collect = IntStream.rangeClosed(1, 1000).parallel().boxed().collect(Collectors.toList());
        System.out.println("collect.size() = " + collect.size());

    }

    /**
     * 并行打印
     */
    private static void parallelPrint() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        list.parallelStream().forEach(i -> {
            System.out.println("thread:"+Thread.currentThread().getName()+",i:"+i);
        });
    }

    /**
     * 获取并行流
     */
    private static void getParallelStream() {
        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        Stream<Integer> stream = list.parallelStream(); //直接获取
//        Stream<Integer> stream = list.stream().parallel(); // 将串行流转为并行流

    }
}
